from surprise import Dataset
from surprise import Reader
from surprise import BaselineOnly, KNNBasic
from surprise import accuracy
from surprise.model_selection import KFold

# 数据读取,先定义一个读取器，以','分隔，第一行跳过
reader = Reader(line_format='user item rating timestamp', sep=',', skip_lines=1)
data = Dataset.load_from_file('./ratings.csv', reader=reader)
#build_full_trainset()方法可用于在整个训练集上训练
#train_set = data.build_full_trainset()

# ALS优化，用字典的形式表示，n_epoch 是迭代次数，reg_u 是uesr项的正则化系数默认值为15，reg_i 是item 项的正则化系数默认值为10(https://surprise.readthedocs.io/en/stable/prediction_algorithms.html?highlight=reg_u#baselines-estimates-configuration)
bsl_options = {'method': 'als','n_epochs': 5,'reg_u': 12,'reg_i': 5}
# SGD优化
#bsl_options = {'method': 'sgd','n_epochs': 5}

#BaselineOnly是基于统计的基准预测线打分，思想是设立基线，并引入user的偏差以及item的偏差
algo = BaselineOnly(bsl_options=bsl_options)

#基于正太分布预测随机评分,假设用户的打分是基于正态分布的
#algo = NormalPredictor()

# 定义K折交叉验证迭代器，K=3
kf = KFold(n_splits=3)
for trainset, testset in kf.split(data):
    algo.fit(trainset)
    predictions = algo.test(testset)
    accuracy.rmse(predictions, verbose=True)

#根据训练集的分布特征随机给出一个预测值
uid = str(196)
iid = str(302)
pred = algo.predict(uid, iid, r_ui=4, verbose=True)
